package com.corn.turtorial.provider.listener;

import com.corn.turtorial.provider.mapper.UserMapper;
import com.corn.turtorial.provider.service.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.StandardCharsets;

/**
 * @author : Jim Wu
 * @version 1.0
 * @function :
 * @since : 2022/5/9 16:00
 */

@Slf4j
@Component
@RocketMQTransactionListener
public class UserTxMessageListener implements RocketMQLocalTransactionListener {
    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private UserMapper userMapper;

    @Transactional
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        String userJson = new String((byte[]) msg.getPayload(), StandardCharsets.UTF_8);
        log.info("执行本地事务,消息:{}",userJson );
        // 执行本地事务
        User user = null;
        try {
            user = objectMapper.readValue(userJson, User.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        int insert = userMapper.insert(user);
        return insert > 0 ? RocketMQLocalTransactionState.COMMIT : RocketMQLocalTransactionState.ROLLBACK;
    }

    @Transactional
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
        String userJson = new String((byte[]) msg.getPayload(), StandardCharsets.UTF_8);
        log.info("回查本地事务,消息:{}", userJson);
        // 回查本地事务
        User user = null;
        try {
            user = objectMapper.readValue(userJson, User.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        User dbUser = userMapper.selectById(user.getId());
        return dbUser != null ? RocketMQLocalTransactionState.COMMIT : RocketMQLocalTransactionState.UNKNOWN;
    }
}
